﻿import idv.ben.gc4flash.axis.*;
import idv.ben.gc4flash.chart.*;
import idv.ben.gc4flash.dataLine.*;
import idv.ben.gc4flash.encode.*;
import idv.ben.gc4flash.fill.*;
import idv.ben.gc4flash.style.*;
import idv.ben.gc4flash.util.*;
/**
* 抽象圖形類別，所有圖形類別要繼承的父類別，請勿直接使用本類別產生圖形。<br>
*/
class idv.ben.gc4flash.chart.AbstractChart {
	private var w:Number;
	private var h:Number;
	/**
	* 圖形種類，這個欄位將會由繼承自 AbstractChart 的其他圖形類別的建構子來提供。<br>
	* <br>
	* Bar Chart:<br>
	* {@link idv.ben.gc4flash.chart.BarChart#CHART_TYPE_BarChart_Horizontal1} = "bhs"<br>
	* {@link idv.ben.gc4flash.chart.BarChart#CHART_TYPE_BarChart_Vertical1} = "bvs"<br>
	* {@link idv.ben.gc4flash.chart.BarChart#CHART_TYPE_BarChart_Horizontal2} = "bhg"<br>
	* {@link idv.ben.gc4flash.chart.BarChart#CHART_TYPE_BarChart_Vertical2} = "bvg"<br>
	* <br>
	* Line Chart:<br>
	* {@link idv.ben.gc4flash.chart.LineChart#CHART_TYPE_LineChart_Simple} = "lc"<br>
	* {@link idv.ben.gc4flash.chart.LineChart#CHART_TYPE_LineChart_XY} = "lxy"<br>
	* <br>
	* Pie Chart:<br>
	* {@link idv.ben.gc4flash.chart.PieChart#CHART_TYPE_PieChart_2D} = "p"<br>
	* {@link idv.ben.gc4flash.chart.PieChart#CHART_TYPE_PieChart_3D} = "p3"<br>
	* <br>
	* Scatter Plots Chart:<br>
	* {@link idv.ben.gc4flash.chart.ScatterPlotsChart#CHART_TYPE_ScatterPlotsChart} = "s"<br>
	* <br>
	* Venn Diagrams Chart:<br>
	* {@link idv.ben.gc4flash.chart.VennDiagramsChart#CHART_TYPE_VennDiagramsChart} = "v"<br>
	*/
	public var typ:String;
	/**
	* 此圖形允許的屬性設定，各種可被設定的屬性定義在 {@link idv.ben.gc4flash.util.Const} 中，包括有：
	* <ul>
	* <li>{@link idv.ben.gc4flash.chart.LineChart} 可用的屬性設定：{@link idv.ben.gc4flash.util.Const#CHT_PARAM_Line_chart}</li>
	* <li>{@link idv.ben.gc4flash.chart.ScatterPlotsChart} 可用的屬性設定：{@link idv.ben.gc4flash.util.Const#CHT_PARAM_Scatter_plot}</li>
	* <li>{@link idv.ben.gc4flash.chart.BarChart} 可用的屬性設定：{@link idv.ben.gc4flash.util.Const#CHT_PARAM_Bar_chart}</li>
	* <li>{@link idv.ben.gc4flash.chart.VennDiagramsChart} 可用的屬性設定：{@link idv.ben.gc4flash.util.Const#CHT_PARAM_Venn_diagram}</li>
	* <li>{@link idv.ben.gc4flash.chart.PieChart} 可用的屬性設定：{@link idv.ben.gc4flash.util.Const#CHT_PARAM_Pie_chart}</li>
	* </ul>
	*/
	public var allowParams:Number;
	/**
	* {@link idv.ben.gc4flash.dataLine.DataLine} 的陣列
	*/
	public var lines:Array;
	private var title:String;
	private var titleColor:String;
	private var titleFontSize:Number;
	private var legends:Array;
	private var colors:Array;
	private var barStyle:Array;
	private var pieChartLabels:Array;
	private var fillArray:Array;
	private var axisArray:Array;
	/**
	* 建構子
	* @param w 圖檔寬度
	* @param h 圖檔高度
	*/
	function AbstractChart(w:Number, h:Number) {
		this.w = w;
		this.h = h;
		
		lines = new Array();
		title = "";
		titleColor = "";
		titleFontSize = 0;
		legends = new Array();
		colors = new Array();
		barStyle = new Array();
		pieChartLabels = new Array();
		fillArray = new Array();
		axisArray = new Array();
	}
	/**
	* 取得圖形組成的 URL 參數字串
	* @param min 要顯示的最小值，用以計算所有數值資料被編碼後結果。
	* @param max 要顯示的最大值，用以計算所有數值資料被編碼後結果。
	* @param encodeType 資料可以使用三種編碼方式：<br>
	*		<ul>
	*		<li>{@link idv.ben.gc4flash.encode.EncodeType#ENCODE_TYPE_SIMPLE} = "s"</li>
	*		<li>{@link idv.ben.gc4flash.encode.EncodeType#ENCODE_TYPE_TEXT} = "t"</li>
	*		<li>{@link idv.ben.gc4flash.encode.EncodeType#ENCODE_TYPE_ENTENDED} = "e"</li>
	*		</ul>
	* @return 依照 encodeType 而有不同的字串格式
	*/
	public function toChartData(min:Number, max:Number, encodeType:String):String {
		var str:String = "chs="+w+"x"+h+"&cht="+typ;
		str += getLineChartData(min, max, encodeType);
		str += getTitleChartData();
		str += getTitleStyleChartData();
		str += getColorsChartData();
		str += getAxisChartData();
		if(this instanceof BarChart){
			str += (BarChart(this)).getBarStyleChartData();
		}
		if(this instanceof PieChart){
			str += (PieChart(this)).getLabelsChartData();
		}
		if(this instanceof LineChart){
			str += (LineChart(this)).getGridLinesStyleChartData();
		}
		if(this instanceof ScatterPlotsChart){
			str += (ScatterPlotsChart(this)).getGridLinesStyleChartData();
		}
		return str;
	}
	//--------------------------------------------------- DataLine
	private function getLineChartData(min:Number, max:Number, encodeType:String):String{
		var encode:IEncode = EncodeType.getEncode(encodeType);
		
		var chartData_data:Array = new Array();
		var chartData_legend:Array = new Array();
		var isValid_legend:Boolean = false;
		var chartData_lineStyle:Array = new Array();
		var isValid_lineStyle:Boolean = false;
		
		for (var i:Number = 0; i<lines.length; i++) {
			var line:DataLine = lines[i].line;
			
			chartData_data.push(line.toChartData(min, max, encode));
			
			if(line instanceof LegendDataLine){
				chartData_legend.push((LegendDataLine(line)).getLegendChartData());
			}else if(line instanceof VennDiagramsDataLine){
				chartData_legend.push((VennDiagramsDataLine(line)).getLegendChartData());
			}else{
				chartData_legend.push("");
			}
			if(chartData_legend[chartData_legend.length-1] != ""){
				//至少有一筆資料
				isValid_legend = true;
			}
			
			if(line instanceof LineChartDataLine){
				chartData_lineStyle.push((LineChartDataLine(line)).getLineStyleChartData())
			}else{
				chartData_lineStyle.push("");
			}
			if(chartData_lineStyle[chartData_lineStyle.length-1] != ""){
				//至少有一筆資料
				isValid_lineStyle = true;
			}
		}
		
		var tmp:String = "&chd="+encodeType+":"+chartData_data.join(encode.getSeparateForEachSet());
		if(isValid_legend){
			tmp += ("&chdl="+chartData_legend.join("|"));
		}
		if(isValid_lineStyle){
			tmp += ("&chls="+chartData_lineStyle.join("|"));
		}

		return tmp;
	}
	//--------------------------------------------------- Title
	/**
	* 設定圖表標題<br>
	* <br>
	* <img src="http://chart.apis.google.com/chart?cht=bvs&chd=s:YUVmw1&chco=FF0000&chs=180x150&chtt=Site+visitors+by+month|January+to+July&chbh=22,4"><br>
	* chtt=Site+visitors+by+month|January+to+July<br>
	* @param title 標題
	*/
	public function setTitle(title:String):Void{
		if(allowParams & Const.PARAM_Chart_title){
			this.title = title;
		}else{
			throw new Error("can't set title!!");
		}
	}
	private function getTitleChartData():String{
		if(title!=""){
			var str:String = title;
			str = str.split(" ").join("+");
			str = str.split("\n").join("|");
			return "&chtt=" + str;
		}else{
			return "";
		}
	}
	//--------------------------------------------------- Title Style
	/**
	* 設定圖表標題風格
	* <br>
	* <img src="http://chart.apis.google.com/chart?cht=bvs&chd=s:YUVmw1&chco=0000FF&chs=180x150&chtt=Site+visitors&chts=0000FF,20&chbh=22,4"><br>
	* chtt=Site+visitors&chts=0000FF,20<br>
	* @param color 顏色，請參考 Google Chart API：<a href="http://code.google.com/apis/chart/#rgb" target="_blank">http://code.google.com/apis/chart/#rgb</a>
	* @param fontSize 字級大小
	*/
	public function setTitleStyle(color:String, fontSize:Number):Void{
		if(allowParams & Const.PARAM_Chart_title_color_fontsize){
			titleColor = color;
			titleFontSize = fontSize;
		}else{
			throw new Error("can't set title style!!");
		}
	}
	private function getTitleStyleChartData():String{
		if(titleColor!="" && titleFontSize>0){
			return "&chts=" + titleColor + "," + titleFontSize;
		}else{
			return "";
		}
	}
	//--------------------------------------------------- Colors
	/**
	* 設定資料顏色
	* <br>
	* <table>
	* <tr>
	* <td><img src="http://chart.apis.google.com/chart?cht=lc&chco=ff0000,00ff00,0000ff&chs=200x125&chd=s:FOETHECat,lkjtf3asv,KATYPSNXJ&chxt=x,y&chxl=0:|Oct|Nov|Dec|1:||20K||60K||100K"></td>
	* <td><img src="http://chart.apis.google.com/chart?cht=lc&chco=ff0000,0000ff&chs=200x125&chd=s:FOETHECat,lkjtf3asv,KATYPSNXJ&chxt=x,y&chxl=0:|Oct|Nov|Dec|1:||20K||60K||100K"></td>
	* </tr>
	* <tr>
	* <td>chco=ff0000,00ff00,0000ff</td>
	* <td>chco=ff0000,0000ff</td>
	* </tr>
	* </table>
	* <br>
	* <table>
	* <tr>
	* <td><img src="http://chart.apis.google.com/chart?cht=bhs&chco=ff0000,00ff00&chs=200x125&chd=s:FOE,THE,Bar&chxt=x,y&chxl=1:|Dec|Nov|Oct|0:||20K||60K||100K|"></td>
	* <td><img src="http://chart.apis.google.com/chart?cht=bhs&chco=ff0000,00ff00,0000ff,&chs=200x125&chd=s:FOE,THE,Bar&chxt=x,y&chxl=1:|Dec|Nov|Oct|0:||20K||60K||100K|"></td>
	* </tr>
	* <tr>
	* <td>chco=ff0000,00ff00</td>
	* <td>chco=ff0000,00ff00,0000ff</td>
	* </tr>
	* </table>
	* <br>
	* <table>
	* <tr>
	* <td><img src="http://chart.apis.google.com/chart?cht=p3&chs=200x90&chd=s:Hellobla&chl=May|Jun|Jul|Aug|Sep|Oct&chco=0000ff"></td>
	* <td><img src="http://chart.apis.google.com/chart?cht=v&chs=200x100&chd=t:100,80,60,30,30,30,10&chco=00ff00,0000ff"></td>
	* </tr>
	* <tr>
	* <td>chco=0000ff</td>
	* <td>chco=00ff00,0000ff</td>
	* </tr>
	* </table>
	* @param colors 資料顏色字串的陣列，["顏色1", "顏色2", ..., "顏色3"]<br>
	* 		顏色字串，請參考 Google Chart API：<a href="http://code.google.com/apis/chart/#rgb" target="_blank">http://code.google.com/apis/chart/#rgb</a>
	*/
	public function setColors(colors:Array):Void{
		if(allowParams & Const.PARAM_Colors){
			this.colors = colors;
		}else{
			throw new Error("can't set colors!!");
		}
	}
	private function getColorsChartData():String{
		if(colors.length>0){
			return "&chco=" + colors.join(",");
		}else{
			return "";
		}
	}	
	//--------------------------------------------------- Axis
	/**
	* 新增一組 {@link idv.ben.gc4flash.axis.Axis} 座標
	* @param axis {@link idv.ben.gc4flash.axis.Axis} 座標
	*/
	public function addAxis(axis:Axis):Void {
		if(allowParams & Const.PARAM_Multiple_axis_labels){
			axisArray.push(axis);
		}else{
			throw new Error("can't set axis!!");
		}
	}	
	private function getAxisChartData():String {
		if(axisArray.length==0){
			return "";
		}
		var tmpValue:String = "";
		//-------------------------------- axis type
		var chartData_type:Array = new Array();
		for(var i:Number=0; i<axisArray.length; i++){
			chartData_type.push(axisArray[i].getTypeChartData());
		}
		if(chartData_type.length>0){
			tmpValue += ("&chxt=" + chartData_type.join(","))
		}
		//-------------------------------- axis labels
		var chartData_labels:Array = new Array();
		for(var i:Number=0; i<axisArray.length; i++){
			var type:String = axisArray[i].getLabelChartData();
			if(type!=""){
				chartData_labels.push(i + type);
			}
		}
		if(chartData_labels.length>0){
			tmpValue += ("&chxl=" + chartData_labels.join("|"))
		}
		//-------------------------------- axis positions
		var chartData_positions:Array = new Array();
		for(var i:Number=0; i<axisArray.length; i++){
			var position:String = axisArray[i].getPositionChartData();
			if(position!=""){
				chartData_positions.push(i + position);
			}
		}
		if(chartData_positions.length>0){
			tmpValue += ("&chxp=" + chartData_positions.join("|"))
		}
		//-------------------------------- axis range
		var chartData_range:Array = new Array();
		for(var i:Number=0; i<axisArray.length; i++){
			var range:String = axisArray[i].getRangeChartData();
			if(range!=""){
				chartData_range.push(i + range);
			}
		}
		if(chartData_range.length>0){
			tmpValue += ("&chxr=" + chartData_range.join("|"))
		}
		//-------------------------------- axis style
		var chartData_style:Array = new Array();
		for(var i:Number=0; i<axisArray.length; i++){
			var style:String = axisArray[i].getStyleChartData();
			if(style!=""){
				chartData_style.push(i + style);
			}
		}
		if(chartData_style.length>0){
			tmpValue += ("&chxs=" + chartData_style.join("|"))
		}
		//-------------------------------- return
		return tmpValue;		
	}
	//--------------------------------------------------- Fill
	/**
	* 新增一組有實做 {@link idv.ben.gc4flash.fill.IFill} 介面的背景填色設定
	* @param fill 有實做 {@link idv.ben.gc4flash.fill.IFill} 介面的背景填色設定
	*/
	public function addFill(fill:IFill):Void {
		if(allowParams & Const.PARAM_Chart_and_background_fill){
			fillArray.push(fill);
		}else{
			throw new Error("can't set fill!!");
		}
	}
	private function getFillChartData():String{
		if(fillArray.length==0){
			return "";
		}
		var tmpValue:String = "&chf=";
		var chartData_fill:Array = new Array();
		for (var i:Number = 0; i<fillArray.length; i++) {
			chartData_fill.push(fillArray[i].toChartData());
		}
		tmpValue += chartData_fill.join("|");
		return tmpValue;
	}
}
